package com.cjt.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cjt.common.dto.StuSubjectDto;
import com.cjt.common.exception.MyRuntimeException;
import com.cjt.common.lang.Const;
import com.cjt.mapper.ScoreMapper;
import com.cjt.pojo.*;
import com.cjt.service.*;
import com.cjt.mapper.SubjetMapper;
import com.cjt.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
* @author Hello
* @description 针对表【subjet】的数据库操作Service实现
* @createDate 2023-03-06 22:29:30
*/
@Service
public class SubjetServiceImpl extends ServiceImpl<SubjetMapper, Subjet>
    implements SubjetService{

    @Autowired
    CollegeSubService collegeSubService;
    @Autowired
    Sub_ScoreService subScoreService;
    @Autowired
    Stu_ScoreService stu_scoreService;
    @Autowired
    CollegeService collegeService;
    @Autowired
    TeacherService teacherService;
    @Autowired
    StuSubjetService stuSubjetService;
    @Autowired
    ScoreMapper scoreMapper;
    @Autowired
    RedisUtil redisUtil;




    //查出全部院系全部的课程
    @Override
    public List<StuSubjectDto> getsub(Integer id) {
        StuSubjectDto stuSubjectDto = new StuSubjectDto();
        List<StuSubjectDto> list = new ArrayList<>();
        List<Long> selectList = selectSub();
        //在院系科目表中获取到全部科目id和院系id
        List<CollegeSub> collegeSubs = collegeSubService.list(new LambdaQueryWrapper<CollegeSub>().eq(CollegeSub::getCollegeId, id));
        Long redi = null;
//        System.out.println(redisUtil.hget(Const.STU_CAKECLAS, SecurityContextHolder.getContext().getAuthentication().getName()));
        Object redis = redisUtil.hget(Const.STU_CAKECLAS, SecurityContextHolder.getContext().getAuthentication().getName());
        if (!Objects.isNull(redis)) {
            redi = Long.valueOf(redis.toString());
        }
        for (int i = 0; i <collegeSubs.size() ; i++) {
            //通过学院id在学员表中找到学院名填入Dto
            College college = collegeService.getById(collegeSubs.get(i).getCollegeId());
            stuSubjectDto.setCollege(college.getName());
            //通过科目id在科目表中找到所有科目
            List<Subjet> subjet = this.list(new LambdaQueryWrapper<Subjet>().eq(Subjet::getId, collegeSubs.get(i).getSubId()));
            for (Subjet subjet1 : subjet) {
                //遍历已选课程id
                for (Long integer : selectList) {
                    //当前外循环院系科目表id与已选科目表id相同，则状态码设置为1
                    if (Objects.equals(integer, collegeSubs.get(i).getSubId())) {
                        stuSubjectDto.setStatus(1);
                        if (Objects.equals(integer,collegeSubs.get(i).getSubId()) && Objects.equals(redi,collegeSubs.get(i).getSubId())) {
                            //TODO 在Redis中拿到临时新增的科目id 判断 是否与当前课程id相等，相等时状态码赋值为2
                            stuSubjectDto.setStatus(2);
                        }
                        break;
                    } else {
                        stuSubjectDto.setStatus(0);
                    }
                }
                //通过科目表中老师id在老师表中找到对应的老师名称
                Teacher teacher = teacherService.getOne(new LambdaQueryWrapper<Teacher>().eq(Teacher::getTeaId, subjet1.getTeaId()));
                if (!ObjectUtil.isEmpty(teacher)) {
                    stuSubjectDto.setTeaName(teacher.getName());
                } else {
                    stuSubjectDto.setTeaName(null);
                }
                stuSubjectDto.setSubName(subjet1.getName());
                stuSubjectDto.setStuid(subjet1.getId());
                StuSubjectDto news = BeanUtil.copyProperties(stuSubjectDto, StuSubjectDto.class);
                list.add(news);
            }
        }
        return list;
    }


    //获取已选科目Id
    private List<Long> selectSub() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<Long> list = new ArrayList<>();
        //学号
        String id = authentication.getName();
        //通过学号获取到成绩学生中间表中的成绩id
        List<Stu_Score> stu_score = stu_scoreService.list(new LambdaQueryWrapper<Stu_Score>().eq(Stu_Score::getStuId, id));
        for (Stu_Score stuScore : stu_score) {
            //通过成绩id获取到科目成绩表中的已选科目id
            Sub_Score sub_score = subScoreService.getOne(new LambdaQueryWrapper<Sub_Score>().eq(Sub_Score::getScoreId, stuScore.getScoreId()));
            //已选科目Id
            Sub_Score news = BeanUtil.copyProperties(sub_score, Sub_Score.class);
            list.add(Long.valueOf(news.getSubId()));
        }
        return list;
    }


    @Transactional
    @Override
    public void cakeCla(Long subId){
        Date date = new Date();
        List<Long> ids = selectSub();
        String userid = SecurityContextHolder.getContext().getAuthentication().getName();
        if (redisUtil.hasKey(Const.STU_CAKECLAS)) {
            throw new MyRuntimeException("400","只能选择一门课程");
        }
        for (Long id : ids) {
            if (Objects.equals(subId, id)) {
                throw new RuntimeException();
            }
        }
        String id = SecurityContextHolder.getContext().getAuthentication().getName();
        StuSubjet stuSubjet = new StuSubjet();
        stuSubjet.setStuId(Long.valueOf(id));
        stuSubjet.setSubId(subId);
        List<Long> longs = selectSub();
        for (Long aLong : longs) {
            if (Objects.equals(subId, aLong)) {
                throw new RuntimeException("操作失误");
            }
        }
        stuSubjetService.save(stuSubjet);
        Score score = new Score();
        score.setStatu(0);
        score.setCreated(date);
        scoreMapper.saveStatu(score);

        Long scoreId = score.getId();
        Sub_Score sub_score = new Sub_Score();
        sub_score.setSubId(subId);
        sub_score.setScoreId(scoreId);
        subScoreService.save(sub_score);
        Stu_Score stu_score = new Stu_Score();
        stu_score.setScoreId(scoreId);
        stu_score.setStuId(Long.valueOf(id));
        stu_scoreService.save(stu_score);
        //TODO 新建临时数据时候往 Redis中存入该科目id 1天
        redisUtil.hset(Const.STU_CAKECLAS, id, subId,86400);

    }

    @Override
    @Transactional
    public void delCla(Long subid) {
        List<Long> ids = selectSub();
        for (Long id : ids) {

            if (Objects.equals(subid, id)) {
                Long scoreId = null;
                String userid = SecurityContextHolder.getContext().getAuthentication().getName();
                //科目id 学号id相同的科目学生表删除
                stuSubjetService.remove(new LambdaQueryWrapper<StuSubjet>()
                        .eq(StuSubjet::getSubId, subid)
                        .eq(StuSubjet::getStuId, userid));
                List<Stu_Score> list = stu_scoreService.list(new LambdaQueryWrapper<Stu_Score>().eq(Stu_Score::getStuId, userid));
                for (Stu_Score stu_score : list) {
                    Sub_Score sub_score = subScoreService.getOne(new LambdaQueryWrapper<Sub_Score>()
                            .eq(Sub_Score::getScoreId, stu_score.getScoreId())
                            .eq(Sub_Score::getSubId, subid));
                    if (!Objects.isNull(sub_score)) {
                        //拿到成绩id
                        scoreId = sub_score.getScoreId();
                        break;
                    }
                }
                stu_scoreService.remove(new LambdaQueryWrapper<Stu_Score>()
                        .eq(Stu_Score::getStuId, userid)
                        .eq(Stu_Score::getScoreId, scoreId));
                subScoreService.remove(new LambdaQueryWrapper<Sub_Score>()
                        .eq(Sub_Score::getScoreId, scoreId)
                        .eq(Sub_Score::getSubId,subid));
                scoreMapper.removeById(scoreId);
                //TODO 删除新增临时课程
                redisUtil.hdel(Const.STU_CAKECLAS, userid);
            }
        }

    }
}




